package com.zy.datareceiver.core.cast;

import com.zy.datareceiver.binsess.monitoring.mapper.MonitoringParameterMapper;
import com.zy.datareceiver.binsess.monitoring.param.query.PointParameters;
import com.zy.datareceiver.binsess.warning.entity.WarningLevel;
import com.zy.datareceiver.binsess.warning.entity.WarningThreshold;
import com.zy.datareceiver.binsess.warning.mapper.WarningLevelMapper;
import com.zy.datareceiver.binsess.warning.mapper.WarningThresholdMapper;
import com.zy.datareceiver.core.common.SpringApplicationContext;
import com.zy.datareceiver.core.common.Tuple2;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

/**
 * 缓存数据字典
 * */
public class CacheDict {
    private static WarningLevelMapper warningLevelMapper = SpringApplicationContext.getBean(WarningLevelMapper.class);
    private static WarningThresholdMapper warningThresholdMapper = SpringApplicationContext.getBean(WarningThresholdMapper.class);
    private static MonitoringParameterMapper monitoringParameterMapper = SpringApplicationContext.getBean(MonitoringParameterMapper.class);

    private static List<PointParameters> pointParameterList = new ArrayList<>();

    private static HashMap<Integer,String> deviceMap = new HashMap<>();
    private static HashMap<Integer,String> pointMap = new HashMap<>();
    private static HashMap<Integer,String> parameterNameEnMap = new HashMap<>();
    private static HashMap<Integer, Tuple2<Integer,String>> warningLevelMap = new HashMap<>();
    private static HashMap<String, WarningThreshold[]> warningThresholdMap = new HashMap<>();

    static{
        init();
    }

    private static void setWarningLevelMap(){
        List<WarningLevel> warningLevelList = warningLevelMapper.selectAll();
        for (WarningLevel warningLevel:warningLevelList) {
            Tuple2<Integer,String> warningLevelTuple = new Tuple2<>(warningLevel.getId(),warningLevel.getLevelName());
            warningLevelMap.put(warningLevel.getId(),warningLevelTuple);
        }
    }

    private static void setWarningThresholdMap(){
        List<WarningThreshold> warningThresholdList = warningThresholdMapper.selectAll();
        for (WarningThreshold warningThreshold:warningThresholdList) {
            String keys = warningThreshold.getPointId()+"_" +warningThreshold.getParameterId();
            if (warningThresholdMap.containsKey(keys)){
                warningThresholdMap.get(keys)[warningThreshold.getLevelId()-1] = warningThreshold;
            }else{
                WarningThreshold[] warningThresholds = new WarningThreshold[3];
                warningThresholds[warningThreshold.getLevelId()-1] = warningThreshold;
                warningThresholdMap.put(keys,warningThresholds);
            }
        }
    }

    public static synchronized String getDeviceNameByPointId(Integer pointId){
        for (PointParameters param:pointParameterList) {
            if (param.getPointId() == pointId){
                return param.getDeviceName();
            }
        }
        return null;
    }

    public static synchronized Integer getDeviceIdByPointId(Integer pointId){
        for (PointParameters param:pointParameterList) {
            if (param.getPointId() == pointId){
                return param.getDeviceId();
            }
        }
        return null;
    }

    public static synchronized String getWarningLevelNameByLevelId(Integer levelId) {
        return (String) warningLevelMap.get(levelId)._2().get();
    }

    public static synchronized WarningThreshold[] getWarningThresholdByPointIdAndParameterId(Integer pointId, Integer paramterId) {
        if (pointId == null || paramterId == null){
            return null;
        }
        String key = pointId+"_"+paramterId;
        return warningThresholdMap.get(key);
    }

    public static String getLevelNameByLevelId(Integer levelId) {
        Tuple2<Integer,String> tuple = warningLevelMap.get(levelId);
        if (tuple == null){
            throw new IllegalArgumentException("指定预警编号不存在");
        }
        return (String) tuple._2().get();
    }

    public static Integer getPointIdByName(String pointName) {
        for (Map.Entry<Integer,String> entity:pointMap.entrySet()) {
            if (StringUtils.equals(entity.getValue(),pointName)){
                return entity.getKey();
            }
        }
        return null;
    }

    public static String getPointNameByPointId(Integer pointId) {
        return pointMap.get(pointId);
    }

    public static Set<String> getParameterNameEnsByPointId(Integer pointId) {
        Set<String> parameterNameEns = new HashSet<>();
        pointParameterList.stream().filter((PointParameters point)->point.getPointId() == pointId)
                .forEach(x->parameterNameEns.add(x.getParameterNameEn()));
        return parameterNameEns;
    }

    public static String getParameterNameByParameterId(Integer parameterId) {
        if (!parameterNameEnMap.containsKey(parameterId)){
            pointParameterList.stream().filter((PointParameters point)->point.getParameterId() == parameterId)
                    .forEach(x->parameterNameEnMap.put(x.getParameterId(),x.getParameterNameEn()));
        }
        return parameterNameEnMap.get(parameterId);
    }

    public static String getUtilByParamterId(int parameterId) {
        for (PointParameters pointParameters:pointParameterList) {
            if (pointParameters.getParameterId() == parameterId){
                return pointParameters.getParameterNameEn();
            }
        }
        return null;
    }



    public static void init(){
        pointParameterList = monitoringParameterMapper.selectAllPointInfo();
        for (PointParameters pointParameters:pointParameterList) {
            deviceMap.put(pointParameters.getDeviceId(),pointParameters.getDeviceName());
            pointMap.put(pointParameters.getPointId(),pointParameters.getPointName());
            parameterNameEnMap.put(pointParameters.getParameterId(),pointParameters.getParameterNameEn());
        }
        setWarningLevelMap();
        setWarningThresholdMap();
    }

    public static Set<Integer> getAllDeviceId(){
        Set<Integer> res = new HashSet<>();

        if (MapUtils.isEmpty(deviceMap)){
            for (PointParameters pointParameters:pointParameterList) {
                res.add(pointParameters.getDeviceId());
            }
        }else{
            res = deviceMap.keySet();
        }
        return res;
    }

    public static Set<Integer> getAllPointId(){
        Set<Integer> res = new HashSet<>();
        if (MapUtils.isEmpty(pointMap)){
            for (PointParameters pointParameters:pointParameterList) {
                res.add(pointParameters.getPointId());
            }
        }else{
            res = pointMap.keySet();
        }
        return res;
    }

    public static Set<Integer> getPointsByDeviceId(Integer deviceId){
        Set<Integer> res = new HashSet<>();
        pointParameterList.stream().filter((PointParameters param)->param.getDeviceId() == deviceId).forEach(x->{
            res.add(x.getPointId());
        });
        return res;
    }

    public static Set<String> getPointNamesByDeviceId(Integer deviceId){
        Set<String> res = new HashSet<>();
        pointParameterList.stream().filter((PointParameters param)->param.getDeviceId() == deviceId).forEach(x->{
            res.add(x.getPointName());
        });
        return res;
    }
}
